package com.steerinfo.dil.config;

import com.steerinfo.framework.utils.misc.IdGenerator;
import com.steerinfo.dil.util.UploadUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

@Component
public class ImageFileUtils implements FileUtils {

    @Value(value = "${prefix.filePrefix}" )
    private String filePrefix;//文件前缀
    @Value(value = "${filePath}" )
    private String path;//文件路径

    public static final HashMap fileTypes = new HashMap();

    static {

        // images

        fileTypes.put("FFD8FF", "jpg");

        fileTypes.put("89504E47", "png");

        fileTypes.put("47494638", "gif");

        fileTypes.put("49492A00", "tif");

        fileTypes.put("424D", "bmp");

        // CAD

        fileTypes.put("41433130", "dwg");

        fileTypes.put("38425053", "psd");

        // 日记本

        fileTypes.put("7B5C727466", "rtf");

        fileTypes.put("3C3F786D6C", "xml");

        fileTypes.put("68746D6C3E", "html");

        // 邮件

        fileTypes.put("44656C69766572792D646174653A", "eml");

        fileTypes.put("D0CF11E0", "doc");

        //excel2003版本文件

        fileTypes.put("D0CF11E0", "xls");

        fileTypes.put("5374616E64617264204A", "mdb");

        fileTypes.put("252150532D41646F6265", "ps");

        fileTypes.put("255044462D312E", "pdf");

        fileTypes.put("504B0304", "docx");

        //excel2007以上版本文件

        fileTypes.put("504B0304", "xlsx");

        fileTypes.put("52617221", "rar");

        fileTypes.put("57415645", "wav");

        fileTypes.put("41564920", "avi");

        fileTypes.put("2E524D46", "rm");

        fileTypes.put("000001BA", "mpg");

        fileTypes.put("000001B3", "mpg");

        fileTypes.put("6D6F6F76", "mov");

        fileTypes.put("3026B2758E66CF11", "asf");

        fileTypes.put("4D546864", "mid");

        fileTypes.put("1F8B08", "gz");

    }


    /**
     * 上传多张图片
     * @param files
     * @return
     * @throws Exception
     */
    @Override
    public synchronized List<String> updateFiles(MultipartFile files[]) throws Exception {
        //首先通过Calendard对象获得年月日
        Calendar calendar= Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day= calendar.get(Calendar.DAY_OF_MONTH);
        //上传文件夹路径
        List<String> urls=new ArrayList<>();
        for (int i=0;i<files.length;i++){
            String url = UploadUtils.uploadFile(files[i], path, File.separator+year+ File.separator+month+ File.separator+day+ File.separator);
            urls.add(url);
        }
        return urls;
    }


    /**
     * 上传单个文件
     * @param file
     * @return
     * @throws Exception
     */
    public String updateFile(MultipartFile file,long workerId) throws Exception {
        //首先通过Calendard对象获得年月日
        Calendar calendar= Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day= calendar.get(Calendar.DAY_OF_MONTH);
        String url = filePrefix + UploadUtils.uploadFile(file, path, File.separator+year+ File.separator+month+ File.separator+day+ File.separator);
        return url;
    }

    /**
     * 下载图片获得字节码
     * @param filePath
     * @return
     * @throws Exception
     */
    @Override
    public Object downloadFile(String filePath) throws Exception {
        File file = new File(filePath);
        if(file.isDirectory()){

            throw new RuntimeException("当前路径是目录");

        }
        byte[] b = bytes(file);
        String type =getFileHeader(b);
        String src="data:image/"+type+";base64,"+ Base64.getEncoder().encodeToString(b);
        return src;
    }




    /**
     * @return 文件头信息
     * @author liang.pan
     * <p>
     * 方法描述：根据输入流获取文件头信息
     */
    public static String getFileHeader(byte[] b) {
        String value = bytesToHexString(b);

        if (StringUtils.startsWith(value, "FFD8FF")) {
            value = value.substring(0, 6);
        }

        //判断什么类型的
        Set set = fileTypes.keySet();
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            String key=iterator.next().toString();
            if (value.contains(key)){
                return fileTypes.get(key).toString();
            }
        }
        return null;
    }

    /**
     * @param src 要读取文件头信息的文件的byte数组
     * @return 文件头信息
     * @author liang.pan
     * <p>
     * 方法描述：将要读取文件头信息的文件的byte数组转换成string类型表示
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        String hv;
        for (int i = 0; i < src.length; i++) {
            // 以十六进制（基数 16）无符号整数形式返回一个整数参数的字符串表示形式，并转换为大写
            hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString();
    }


    public byte[] bytes(File file) throws Exception {
        FileInputStream fin = new FileInputStream(file);
        try {
            //可能溢出,简单起见就不考虑太多,如果太大就要另外想办法，比如一次传入固定长度byte[]
            byte[] bytes  = new byte[fin.available()];
            //将文件内容写入字节数组，提供测试的case
            fin.read(bytes);
            fin.close();
            return bytes;
        }catch (Exception ex){
            throw ex;
        }
        finally {
            if (null != fin) {

                try {

                    fin.close();

                } catch (IOException e) {

                }

            }
        }
    }
}